{% do view.registerAssetBundle("craft\\web\\assets\\vue\\VueAsset") %}

{% if (suggestEnvVars ?? false) and suggestions is not defined %}
    {% set suggestions = craft.cp.getEnvSuggestions(suggestAliases ?? false) %}
{% endif %}

{%- set id = id ?? "autosuggest#{random()}" %}
{%- set containerId = "#{id}-container" %}
{%- set autosuggestId = "#{id}-autosuggest" %}

{%- set class = (class ?? [])|explodeClass|merge([
    'text',
    (disabled ?? false) ? 'disabled' : null,
    not (size ?? false) ? 'fullwidth' : null,
]|filter) %}

<div id="{{ containerId }}" class="autosuggest-container">
    {% verbatim %}
    <vue-autosuggest
        :suggestions="filteredOptions"
        :get-suggestion-value="getSuggestionValue"
        :input-props="inputProps"
        :limit="limit"
        :component-attr-id-autosuggest="id"
        @selected="onSelected"
        @focus="updateFilteredOptions"
        @blur="onBlur"
    >
        <template slot-scope="{suggestion}">
            {{suggestion.item.name || suggestion.item}}
            <span v-if="suggestion.item.hint" class="light">– {{suggestion.item.hint}}</span>
        </template>
    </vue-autosuggest>
    {% endverbatim %}
</div>

{% js %}
new Vue({
    el: "#{{ containerId|namespaceInputId|e('js') }}",

    data() {
        {% block data %}
        var data = {{ {
            query: '',
            selected: '',
            filteredOptions: [],
            suggestions: suggestions ?? [],
            id: autosuggestId,
            inputProps: {
                class: class|join(' '),
                initialValue: value ?? '',
                style: style ?? '',
                id: id|namespaceInputId,
                name: (name ?? '')|namespaceInputName,
                size: size ?? '',
                maxlength: maxlength ?? '',
                autofocus: autofocus ?? false,
                disabled: disabled ?? false,
                title: title ?? '',
                placeholder: placeholder ?? '',
            },
            limit: limit ?? 5
        }|json_encode|raw }};
        data.inputProps.onInputChange = this.onInputChange;
        {% endblock %}
        return data;
    },

    methods: {
        {% block methods %}
        onInputChange(q) {
            this.query = (q || '').toLowerCase();
            this.updateFilteredOptions();
        },
        updateFilteredOptions() {
            if (this.query === '') {
                this.filteredOptions = this.suggestions;
                return;
            }

            var filtered = [];
            var i, j, sectionFilter, item, name;
            var that = this;

            for (i = 0; i < this.suggestions.length; i++) {
                sectionFilter = [];
                for (j = 0; j < this.suggestions[i].data.length; j++) {
                    item = this.suggestions[i].data[j];
                    if (
                        (item.name || item).toLowerCase().indexOf(this.query) !== -1 ||
                        (item.hint && item.hint.toLowerCase().indexOf(this.query) !== -1)
                    ) {
                        sectionFilter.push(item.name ? item : {name: item});
                    }
                }
                if (sectionFilter.length) {
                    sectionFilter.sort(function(a, b) {
                        var scoreA = that.scoreItem(a, this.query);
                        var scoreB = that.scoreItem(b, this.query);
                        if (scoreA === scoreB) {
                            return 0;
                        }
                        return scoreA < scoreB ? 1 : -1;
                    });
                    filtered.push({
                        label: this.suggestions[i].label || null,
                        data: sectionFilter.slice(0, this.limit)
                    });
                }
            }

            this.filteredOptions = filtered;
        },
        scoreItem(item) {
            var score = 0;
            if (item.name.toLowerCase().indexOf(this.query) !== -1) {
                score += 100 + this.query.length / item.name.length;
            }
            if (item.hint && item.hint.toLowerCase().indexOf(this.query) !== -1) {
                score += this.query.length / item.hint.length;
            }
            return score;
        },
        onSelected(option) {
            this.selected = option.item;

            // Bring focus back to the input if they selected an alias
            if (option.item.name[0] == '@') {
                var input = this.$el.querySelector('input');
                input.focus();
                input.selectionStart = input.selectionEnd = input.value.length;
            }
        },
        getSuggestionValue(suggestion) {
            return suggestion.item.name || suggestion.item;
        },
        onBlur(e) {
            // Clear out the autosuggestions if the focus has shifted to a new element
            if (e.relatedTarget) {
                this.filteredOptions = [];
            }
        },
        {% endblock %}
    }
})
{% endjs %}
